<!--
 * @Description: ------------ fileDescription -----------
 * @Author: snows_l snows_l@163.com
 * @Date: 2025-01-11 22:05:58
 * @LastEditors: snows_l snows_l@163.com
 * @LastEditTime: 2025-11-05 15:39:30
 * @FilePath: \BLOG\src\views\codeStore\index.vue
-->
<template>
  <div class="page-wrap">
    <PageTopCover :moduleTitle="'Code仓库'" :imgIcon="'code-store.svg'" :coverImg="getOnlineImgUrl('87')" :isMobile="isMobi" :modulDesc="''" :isArticle="false"></PageTopCover>

    <div class="page-container-wrap" :class="{ 'm-page-container-wrap': isMobi }">
      <div class="max-width-wrap">
        <div class="page-content-inner">
          <div class="shengming">
            <div class="sm-title">特此声明：</div>
            <div class="sm-item">
              以下所有代码仓库（live2d看板娘除外, 看板娘是别个大佬写的，我只是自定义适配了一下我的BLOG）均为
              <span>个人开源项目</span>
              。请不要用于商业用途，否则后果自负。 如果喜欢或者帮助到您，可以点个
              <span>star</span>
              或者
              <span>fork</span>
              鼓励一下，也欢迎大家提出意见和建议，共同进步。
            </div>
            <div class="sm-item red">
              最初并没有想过要开源，所以代码质量可能不是很完美，不喜勿喷。其次由于改成开源需要自己去剔除个人隐私信息，可能涉及没有剔除完全的情况，如发现请及时联系本站长删除，谢谢🥺🥺🥺🥺🥺，请谨慎使用。
            </div>
          </div>
          <div class="code-store-list-wrap">
            <div class="content-title">此 Blog 代码仓库地址：</div>
            <div class="code-store-list">
              <div
                class="code-store-item hover-shadow pointer intersection-observer link"
                :data-tip="item.name"
                @click="handleTo(item)"
                v-for="(item, index) in bozhuLinks"
                :key="index">
                <div class="code-store-item-bg" :style="{ backgroundImage: 'url(' + item.logo + ')' }"></div>
                <div class="code-store-item-img">
                  <img :src="item.logo" />
                </div>
                <div class="code-store-info-wrap">
                  <div class="code-store-item-title">
                    {{ item.name }}
                  </div>
                  <div class="code-store-item-content">
                    {{ item.profile }}
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="code-store-list-wrap">
            <div class="content-title">BLOG涉及整套服务的 代码仓库：</div>
            <div class="code-store-list">
              <div
                class="code-store-item hover-shadow pointer intersection-observer link"
                :data-tip="item.name"
                @click="handleTo(item)"
                v-for="(item, index) in otherLinks"
                :key="index">
                <div class="code-store-item-bg" :style="{ backgroundImage: 'url(' + item.logo + ')' }"></div>
                <div class="code-store-item-img">
                  <img :src="item.logo" />
                </div>
                <div class="code-store-info-wrap">
                  <div class="code-store-item-title">
                    {{ item.name }}
                  </div>
                  <div class="code-store-item-content">
                    {{ item.profile }}
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="code-store-list-wrap da-shang" v-if="store.projectConfig.showDonate == 'true'">
            <div class="da-shang-title quote">
              <div class="da-shang-title-title">打赏支持</div>
              <div class="da-shang-title-text">
                如果你觉得这个项目帮助到了你，你可以请站长喝杯咖啡表示鼓励 ☕️，
                <span class="high-light">1分</span>
                也是爱😘。
              </div>
              <div class="da-shang-title-text" style="margin-top: 10px">
                打赏请
                <span class="high-light">备注</span>
                您的
                <span class="high-light">昵称、留言信息、主页链接（可不填）</span>
                ，感谢支持！
              </div>
            </div>
            <div class="da-shang-img">
              <img class="intersection-observer" :src="getOnlineImgUrl('alipay', '/imgs/common', 'jpg')" alt="alipay" />
              <img class="intersection-observer" :src="getOnlineImgUrl('pay', '/imgs/common', 'jpg')" alt="pay" />
            </div>

            <div class="donate-user-wrap" style="margin-top: 20px">
              <div class="content-title">打赏名单：</div>
              <div class="donate-user-list code-store-list" v-if="state.userList.length">
                <div
                  class="donate-item code-store-item intersection-observer"
                  :class="[item.url ? 'hover-shadow kbn-custom pointer' : '']"
                  :data-tip="'想要前往 「' + item.name + '」 的主页吗？'"
                  @click="handleTo(item)"
                  v-for="(item, index) in state.userList"
                  :key="item.name + index">
                  <div
                    class="code-store-item-bg"
                    :style="{ backgroundImage: 'repeating-linear-gradient(45deg, #f0f0f0, #f0f0f0 10px, transparent 10px, transparent 20px,' + item.color + ')' }"></div>
                  <div class="avatar" :style="{ color: item.color, borderColor: item.color }">{{ item.avatar }}</div>
                  <div class="user-name">
                    <div class="name">{{ item.name }}</div>
                    <div>
                      <span class="money">{{ item.money }}</span>
                      元
                    </div>
                    <ToolTip :content="item.profile">
                      <div class="profile">
                        {{ item.profile }}
                      </div>
                    </ToolTip>
                  </div>
                </div>
              </div>
              <div class="no-msg" v-else>
                <Empty :text="'暂无打赏名单~'" :loadingText="'打赏名单拼命加载中...'" :loading="state.loading"></Empty>
              </div>
            </div>
            <div class="botom-wrap" style="display: flex; justify-content: center; align-items: center">
              <LoadingMore
                v-if="store.projectConfig.pageType == 'more'"
                :loading="state.loading"
                :hasMore="state.isMore"
                :length="state.userList.length"
                @loadMore="handleLoadMore"></LoadingMore>
              <CustomPage v-else :page="state.page" @change="handlePageChange" :loading="state.loading" scorllTop="da-shang"></CustomPage>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { getDonateList } from '@/api/donate'; // 假设 DonateResponse 是 API 返回值的类型
import useIntersectionObserver from '@/hooks/useIntersectionObserver';
import useResize from '@/hooks/useResize';
import { useAppStore } from '@/store/app';
import { getImgIcon, getOnlineImgUrl } from '@/utils/common';
import { live2dReloadElement, live2dShowMessage } from '@/utils/live2d';
import { getRandomColor } from '@/utils/theme';
import { onMounted, onUpdated, reactive } from 'vue';

interface ProjectLink {
  name: string;
  profile: string;
  logo: string;
  url?: string;
}

interface DonateUser {
  name: string;
  profile: string;
  avatar: string;
  money: number;
  color?: string;
}

const store = useAppStore();

const { isMobi } = useResize();
useIntersectionObserver();

const state = reactive<{
  loading: boolean;
  userList: DonateUser[];
  isMore: boolean;
  page: {
    page: number;
    size: number;
    total: number;
  };
}>({
  loading: false,
  userList: [],
  isMore: true,
  page: {
    page: 1,
    size: 9,
    total: 0
  }
});

const bozhuLinks: ProjectLink[] = [
  {
    name: '冬七 の Blog',
    profile: '本站 （前vue3后nodejs，移动端适配）',
    logo: getImgIcon('blog.svg'),
    url: 'https://gitee.com/snows_l/Blog'
  }
];

const otherLinks: ProjectLink[] = [
  {
    name: 'Blog 综合后台管理系统',
    profile: 'vue3 + nodejs，集成H5端',
    logo: getImgIcon('backstage.svg'),
    url: 'https://gitee.com/snows_l/open-blog-backstage'
  },
  {
    name: 'Nodejs 后端服务',
    profile: 'Blog & 综合后台管理系统 后端服务，基于Nodejs + Express + mySql',
    logo: getImgIcon('server.svg'),
    url: 'https://gitee.com/snows_l/open-node-server'
  },
  {
    name: '数据库 基础表结构',
    profile: '数据库 基础表结构（没有任何数据），导入sql文件即可',
    logo: getImgIcon('sql.svg'),
    url: 'https://gitee.com/snows_l/open-base-sql'
  },
  {
    name: '看板娘 源码',
    profile: 'Blog live2d-source看板娘',
    logo: getImgIcon('live2d.png'),
    url: 'https://gitee.com/snows_l/live2d-source'
  }
];

const getDonateUserList = (scorllTopCallback?: () => void): void => {
  state.loading = true;
  getDonateList(state.page).then((res: any) => {
    if (res.code === 200) {
      if (store.projectConfig.pageType === 'more') {
        state.userList = [...state.userList, ...res.data];
      } else {
        state.userList = res.data;
      }
      state.userList.forEach(item => {
        item.color = getRandomColor();
      });
      state.page.total = res.total;
      if (state.userList.length >= res.total) {
        state.isMore = false; // 已经没有更多数据了
      }
      scorllTopCallback && scorllTopCallback();
      state.loading = false;
    }
  });
};
getDonateUserList();

const handlePageChange = (page: number, size: number, scorllTopCallback: () => void): void => {
  state.page.page = page;
  state.page.size = size;
  getDonateUserList(scorllTopCallback);
};

// 加载更多
const handleLoadMore = (): void => {
  state.page.page++;
  getDonateUserList();
};

// 点击跳转
const handleTo = (item: ProjectLink): void => {
  if (item.url) {
    window.open(item.url, '_blank');
  }
};

onMounted(() => {
  live2dShowMessage('欢迎访问我的代码仓库，有什么问题可以联系我，我会尽快回复。');
});

onUpdated(() => {
  live2dReloadElement();
});
</script>

<style lang="scss" scoped>
.shengming {
  padding: 20px 0;
  color: var(--text-color);
  font-size: 16px;
  .sm-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 10px;
  }
  .sm-item {
    text-indent: 32px;
    line-height: 30px;
    span {
      color: var(--theme-color);
    }
  }
  .red {
    color: red;
    margin-top: 10px;
  }
}
.code-store-list-wrap {
  margin-top: 20px;
  padding: 20px 10px;
  background-color: var(--bg-content-color);
  border-radius: var(--border-radius-2);
  box-shadow: var(--box-shadow);
  .content-title {
    font-size: 16px;
    font-weight: bold;
    line-height: 40px;
    padding-left: 10px;
  }
  .code-store-list {
    display: flex;
    flex-wrap: wrap;
    .code-store-item {
      border-radius: var(--border-radius-2);
      width: 280px;
      padding: 20px 10px;
      background-color: var(--msg-bg-color);
      box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
      margin: 10px 10px;
      border: 1px solid #fff;
      display: flex;
      align-items: center;
      position: relative;
      overflow: hidden;
      .code-store-item-bg {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
        background-size: 1000% 1000%;
        background-position: center;
        filter: blur(80px);
      }

      .code-store-item-img {
        width: 70px;
        height: 70px;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 22px;
        color: var(--text-color);
        font-weight: bolder;
        img {
          transition: transform 0.5s ease;
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
      }
      &:hover {
        img {
          transform: scale(1.1);
        }
      }

      .code-store-info-wrap {
        flex: 1;
        margin-left: 20px;
        .code-store-item-title {
          font-size: 16px;
          font-weight: bold;
          // text-align: center;
          color: var(--text-color);
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 1; /* 定义文本的行数 */
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .code-store-item-content {
          font-size: 12px;
          line-height: 18px;
          font-weight: bold;
          margin-top: 10px;
          // text-align: center;
          color: var(--text-color);
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 2; /* 定义文本的行数 */
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
  }
  .donate-user-list {
    .donate-item {
      padding: 10px 20px;
      height: 80px;
      &:hover {
        .avatar {
          transform: scale(1.1);
        }
      }
      .avatar {
        width: 50px;
        height: 50px;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 30px;
        line-height: 30px;
        color: var(--text-color);
        font-weight: bolder;
        border-radius: 10px;
        border: 1px solid var(--border-color);
        margin-right: 20px;
        background-color: var(--bg-content-color);
        transition: transform 0.5s ease;
      }
      .user-name {
        height: 100%;

        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: space-around;
        .name {
          font-size: 16px;
          font-weight: bold;
        }
        .money {
          font-size: 18px;
          color: var(--theme-color);
          font-weight: bold;
          margin-right: 10px;
        }
        .profile {
          width: 168px;
          font-size: 12px;
          line-height: 18px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
  }
}
.da-shang {
  .da-shang-title {
    .da-shang-title-title {
      font-size: 20px;
      font-weight: 600;
      margin-bottom: 10px;
    }
    .da-shang-title-text {
      font-size: 16px;
    }
  }
  .da-shang-img {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    img {
      border-radius: var(--border-radius-2);
      overflow: hidden;
      margin: 20px auto;
      width: 300px;
      height: 320px;
      // object-fit: cover;
      box-shadow: var(--box-shadow);
    }
  }
}

.m-page-container-wrap {
  .max-width-wrap {
    width: var(--content-max-width-m) !important;
    .code-store-list-wrap {
      padding: 10px !important;
      .content-title {
        padding-left: 5px !important;
      }
      .code-store-list {
        justify-content: space-between !important;
        .code-store-item {
          width: 100% !important;
          margin: 10px 2px !important;
        }
        .donate-item {
          .user-name {
            width: calc(100% - 80px) !important;
            .profile {
              width: 100% !important;
            }
          }
        }
      }
    }
  }
}

.dark {
  .code-store-item {
    border-color: var(--border-color) !important;
  }
}
</style>
